package org.sunrise.game.client.main.frame;

import lombok.Getter;
import lombok.Setter;
import org.sunrise.game.client.client.PlayerInfo;
import org.sunrise.game.client.client.SocketClientManager;
import org.sunrise.game.client.gen.MapProto;
import org.sunrise.game.client.gen.TopicProto;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Getter
@Setter
public class MapFrame extends JFrame {
    public static MapFrame instance;
    private int playerX; // X 坐标
    private int playerY; // Y 坐标
    private int mapSize = 600;
    private Map<String, PlayerInfo> otherPlayers = new ConcurrentHashMap<>(); // 存储其他玩家的信息

    public MapFrame() {
        setTitle("Map");
        setSize(mapSize, mapSize);
        setResizable(false);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setLocationRelativeTo(null); // 窗口居中
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                int targetX = e.getX(); // 点击的 X 坐标
                int targetY = e.getY(); // 点击的 Y 坐标
                moveTo(targetX, targetY); // 移动玩家
            }
        });
        repaint();
    }

    // 移动玩家到指定位置
    public void moveTo(int targetX, int targetY) {
        targetX = Math.max(15, Math.min(mapSize - 15, targetX));
        targetY = Math.max(15, Math.min(mapSize - 15, targetY));

        MapProto.MC2S_Move moveData = MapProto.MC2S_Move.newBuilder()
                .setMapPostX(targetX)
                .setMapPostY(targetY)
                .build();

        SocketClientManager.getInstance().sendMsg(TopicProto.MBasePacketData.newBuilder()
                .setPacketType(TopicProto.TOPIC.TOPIC_TYPE_MAP)
                .setPacketId(MapProto.FROM_CLIENT.C2S_Move_VALUE)
                .setPacketData(moveData.toByteString())
                .build());

        // 获取当前玩家的旧位置
        int oldX = this.playerX;
        int oldY = this.playerY;

        // 更新玩家的位置
        this.playerX = targetX;
        this.playerY = targetY;

        // 获取需要重绘的区域，包括名字的范围 (适当增加高度以包括名字区域)
        Rectangle oldBounds = getPlayerBounds(oldX, oldY);
        Rectangle newBounds = getPlayerBounds(playerX, playerY);

        // 先重绘旧位置，再重绘新位置
        repaint(oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height); // 清除旧位置
        repaint(newBounds.x, newBounds.y, newBounds.width, newBounds.height); // 绘制新位置
    }

    private Rectangle getPlayerBounds(int x, int y) {
        int rectWidth = 40;  // 长方形的宽度
        int rectHeight = 20; // 长方形的高度
        int nameHeight = 10; // 玩家名字的高度
        return new Rectangle(x - rectWidth / 2, y - rectHeight / 2 - nameHeight, rectWidth, rectHeight + nameHeight);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        // 绘制玩家自己为长方形
        g.setColor(Color.BLUE);
        int rectWidth = 40;
        int rectHeight = 20;
        g.fillRect(playerX - rectWidth / 2, playerY - rectHeight / 2, rectWidth, rectHeight);

        // 在长方形内绘制玩家名字，居中对齐
        g.setColor(Color.WHITE); // 使用白色字体
        String playerName = SocketClientManager.getInstance().getUid();
        FontMetrics fm = g.getFontMetrics();
        int nameWidth = fm.stringWidth(playerName);
        int nameX = playerX - nameWidth / 2;
        int nameY = playerY + fm.getHeight() / 4; // 将文字放在长方形的中间高度
        g.drawString(playerName, nameX, nameY);

        // 绘制其他玩家
        for (PlayerInfo player : otherPlayers.values()) {
            g.setColor(Color.RED); // 用不同颜色区分其他玩家
            g.fillRect(player.getX() - rectWidth / 2, player.getY() - rectHeight / 2, rectWidth, rectHeight);

            // 绘制其他玩家名字
            g.setColor(Color.WHITE); // 其他玩家的名字也用白色字体
            String otherPlayerName = player.getName();
            int otherNameWidth = fm.stringWidth(otherPlayerName);
            int otherNameX = player.getX() - otherNameWidth / 2;
            int otherNameY = player.getY() + fm.getHeight() / 4;
            g.drawString(otherPlayerName, otherNameX, otherNameY);
        }
    }

    // 移动其他玩家
    public void moveOtherPlayer(String playerId, int newX, int newY) {
        PlayerInfo player = otherPlayers.get(playerId);
        if (player != null) {
            int oldX = player.getX();
            int oldY = player.getY();
            player.setX(newX);
            player.setY(newY);

            // 获取旧位置的边界
            Rectangle oldBounds = getPlayerBounds(oldX, oldY);
            repaint(oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height);

            // 获取新位置的边界
            Rectangle newBounds = getPlayerBounds(newX, newY);
            repaint(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
        }
    }
}